#include <algorithm>
#include <ctime>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

/*
C++ STL中的绑定器 std::bind1st  std::bind2nd 如何使用 其实现原理
绑定器+二元函数对象 =》 一元函数对象
C++ STL中的绑定器
bind1st + greater ==> bool operator()(70, const _Ty& _Right);
std::bind1st(std::greater<int>(),70)

bind2nd + less ==> bool operator()(const _Ty& _Left, 70)
std::bind2nd(std::less<int>(),70)

其最终目的是
使用绑定器将二元函数对象修改为一元函数对象，通过预先绑定二元函数对象的操作数中的一个
*/
template <typename Container>
void printContainer(const Container& c) {
    for (auto it = c.begin(); it != c.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
}

// 自定义实现泛型算法
template <typename Iterator, typename Compare>
Iterator my_find_if(Iterator first, Iterator last, Compare comp) {
    for (; first != last; ++first) {
        if (comp(*first)) {  // comp.operator()(*first)
            return first;
        }
    }
    return last;
}

// 自定义实现一元函数对象
// Compare 为二元函数对象类型, T为该二元函数对象处理的数据类型
template <typename Compare, typename T>
class _MyBind1st {
public:
    _MyBind1st(Compare comp, T val) : _comp(comp), _val(val) {
    }

    bool operator()(const T& second) {
        return _comp(_val, second);
    }

private:
    Compare _comp;  // 二元函数对象
    T _val;
};
template <typename Compare, typename T>
class _MyBind2nd {
public:
    _MyBind2nd(Compare comp, T val) : _comp(comp), _val(val) {
    }

    bool operator()(const T& first) {
        return _comp(first, _val);
    }

private:
    Compare _comp;  // 二元函数对象
    T _val;
};

// 自定义实现绑定器
template <typename Compare, typename T>
_MyBind1st<Compare, T> my_bind1st(Compare comp, const T& val) {
    return _MyBind1st<Compare, T>(comp, val);
}

template <typename Compare, typename T>
_MyBind2nd<Compare, T> my_bind2nd(Compare comp, const T& val) {
    return _MyBind2nd<Compare, T>(comp, val);
}

int main() {
    std::vector<int> v;
    srand(time(nullptr));

    for (int i = 0; i < 20; ++i) {
        v.push_back(rand() % 100 + 1);
    }
    printContainer(v);

    std::sort(v.begin(), v.end());
    printContainer(v);  // ascending order

    std::sort(v.begin(), v.end(), std::greater<int>());
    printContainer(v);  // descending order

    // 将70按顺序插入容器v中，寻找第一个小于70的数字，插入到该数字之前，以保证有序
    // bind1st + greater ==> bool operator()(70, const _Ty& _Right);
    // bind2nd + less ==> bool operator()(const _Ty& _Left, 70)
    auto it_find =
        std::find_if(v.begin(), v.end(),
                     std::bind1st(std::greater<int>(),
                                  70));  // 返回第一个满足条件70>x的x的迭代器
    if (it_find != v.end()) {
        v.insert(it_find, 70);
    }
    printContainer(v);

    // 使用自定义实现的泛型算法和绑定器实现同样的需求
    auto it_find2 =
        my_find_if(v.begin(), v.end(), my_bind1st(std::greater<int>(), 80));
    if (it_find2 != v.end()) {
        v.insert(it_find2, 80);
    }
    printContainer(v);

    auto it_find3 =
        my_find_if(v.begin(), v.end(), my_bind2nd(std::less<int>(), 90));
    if (it_find3 != v.end()) {
        v.insert(it_find3, 90);
    }
    printContainer(v);
    return 0;
}
